feat: adopt announcePlannedUpgrade for PDPVerifier#234
Merged
wjmelements merged 4 commits intoFilOzone:mainfrom Nov 26, 2025
Merged
Conversation
c209428 to
48b0e95
Compare
f966cb3 to
f19e5fc
Compare
wjmelements
requested changes
Nov 26, 2025
- made nextUpgrade public removed the getter - reverted the one-step process only have the 2 step mechanism - some fixes in scripts
wjmelements
reviewed
Nov 26, 2025
Comment on lines
75
to
79
| else | ||
| # Old one-step mechanism: direct upgrade without announcement | ||
| echo "No planned upgrade detected, using one-step mechanism (direct upgrade)" | ||
| echo "WARNING: This is the legacy upgrade path. For new deployments, use announce-planned-upgrade.sh first." | ||
| fi |
Contributor
There was a problem hiding this comment.
The pending upgrade being zero means that they did not announcePlannedUpgrade or that the upgrade was already completed.
Contributor
There was a problem hiding this comment.
See how cast call behaves when the call reverts due to missing method. It is probably not going to return ZERO_ADDRESS.
Contributor
Author
There was a problem hiding this comment.
yes it is giving exit codes so i was able to distinguish that way, please check now
wjmelements
pushed a commit
to FilOzone/filecoin-services
that referenced
this pull request
Nov 26, 2025
## Summary This PR covers the `ServiceProviderRegistry` side of [FS #355](#355) by adopting the `announcePlannedUpgrade` pattern already used by `FilecoinWarmStorageService`. PDPVerifier changes are implemented in a separate PR in [`pdp`](FilOzone/pdp#234) and are not included here. ## Changes ### ServiceProviderRegistry contract - Add `PlannedUpgrade` struct and `nextUpgrade` storage field - Add `UpgradeAnnounced(PlannedUpgrade)` event - Implement: - `announcePlannedUpgrade(PlannedUpgrade plannedUpgrade)` — owner-only, validates code size and `afterEpoch > block.number`, stores the plan and emits `UpgradeAnnounced` - `getNextUpgrade() returns (address nextImplementation, uint96 afterEpoch)` — exposes the planned upgrade via the proxy - Update `_authorizeUpgrade(address newImplementation)` to: - Require `newImplementation == nextUpgrade.nextImplementation` - Require `block.number >= nextUpgrade.afterEpoch` - Clear the stored plan on successful upgrade - Update `migrate(string newVersion)` to: - `public onlyProxy onlyOwner reinitializer(2)` - Emit `ContractUpgraded(newVersion, ERC1967Utils.getImplementation())` ### Upgrade scripts - Add `tools/announce-planned-upgrade-registry.sh` - Announces a planned upgrade for a `ServiceProviderRegistry` proxy using `announcePlannedUpgrade((address,uint96))` - Add `tools/upgrade-registry.sh` - Reads `getNextUpgrade()` from the registry proxy - Verifies the planned implementation and `afterEpoch` - Calls `upgradeToAndCall(address,bytes)` with `migrate(string)` and the desired version - Verifies the final implementation using the standard ERC-1967 implementation slot (`0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`) ### Tests - Extend `ServiceProviderRegistryTest` to cover: - `testAnnouncePlannedUpgrade` — happy-path announce and gated upgrade flow - `testAnnouncePlannedUpgradeOnlyOwner` — only the owner can announce - `testAnnouncePlannedUpgradeInvalidImplementation` — revert on non-contract implementation - `testAnnouncePlannedUpgradeInvalidEpoch` — revert when `afterEpoch <= block.number` - `testOnlyOwnerCanUpgrade` — validates that: - Non-owner upgrades revert - Owner can upgrade after a valid announcement and epoch gating Closes : #355
wjmelements
approved these changes
Nov 26, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adopts the
announcePlannedUpgradeflow forPDPVerifier, mirroring the pattern used byFilecoinWarmStorageServiceandServiceProviderRegistry.Changes
PlannedUpgradestruct,nextUpgradestorage andUpgradeAnnouncedeventannouncePlannedUpgrade(PlannedUpgrade)– owner-only, validates code size andafterEpoch > block.numbergetNextUpgrade() -> (address nextImplementation, uint96 afterEpoch)migrate()→external onlyProxy onlyOwner reinitializer(2)emittingContractUpgraded(VERSION, implementation)_authorizeUpgrade()now checksnewImplementation == nextUpgrade.nextImplementationandblock.number >= nextUpgrade.afterEpoch, then clearsnextUpgradetools/to:upgradeToAndCallafter verifying the plan and epochTests
test/ERC1967Proxy.t.soltestUpgradeImplementation:PlannedUpgradeon the proxy and rolls pastafterEpochbefore callingupgradeToAndCalltestUpgradeFromNonOwnerNoGood:PlannedUpgradeas the ownerupgradeToAndCallstill revertstest/PDPVerifier.t.sol(PDPVerifierMigrateTest)pdpVerifierpointing at theMyERC1967ProxyinstancetestAnnouncePlannedUpgrade– happy path: announce, verifygetNextUpgrade, then upgrade afterafterEpochtestAnnouncePlannedUpgradeOnlyOwner– non‑owner announce revertstestAnnouncePlannedUpgradeInvalidImplementation– invalidnextImplementation(no code) revertstestAnnouncePlannedUpgradeInvalidEpoch–afterEpoch <= block.numberrevertstestMigrate:upgradeToAndCall→migrate()runs and emitsContractUpgradedInvalidInitialization()from the secondupgradeToAndCallCloses: FilOzone/filecoin-services#355